﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System.Xml;
using System.Xml.Linq;

namespace Pavilion
{
    public class ResourceManager
    {
        private static ResourceManager instance;
        static public ResourceManager Instance { get { return (instance == null) ? new ResourceManager() : instance; } }

        public NotifiableCollection<ResourceItem> ResourceCollection { get { return resourceDictionary.ValueCollection; } }

        private NotifiableDictionary<string, ResourceItem> resourceDictionary;
        private AnimationXmlSerializer animationSerializer;
        private ScriptXmlSerializer scriptXmlSerializer;
        private NameChangedDelegate resourceNameChangedDelegate;

        private ResourceManager()
        {
            instance = this;

            resourceDictionary = new NotifiableDictionary<string, ResourceItem>();
            animationSerializer = new AnimationXmlSerializer();
            scriptXmlSerializer = new ScriptXmlSerializer();

            resourceNameChangedDelegate = (oldName, newName) => resourceDictionary.ReplaceKey(oldName, newName);
        }

        public void UnloadContent()
        {
            foreach (ResourceItem resourceItem in resourceDictionary.ValueCollection)
                resourceItem.Dispose();

            resourceDictionary.Clear();
        }

        public void AddResourceItem(ResourceItem resourceItem)
        {
            resourceDictionary.Add(resourceItem.Name, resourceItem);

            resourceItem.NameChanged += resourceNameChangedDelegate;
        }

        public bool RemoveResource(string resourceName)
        {
            resourceDictionary[resourceName].NameChanged -= resourceNameChangedDelegate;

            return resourceDictionary.Remove(resourceName);
        }

        public ResourceItem LoadResource(string resourceName)
        {
            if (resourceDictionary.ContainsKey(resourceName))
                return resourceDictionary[resourceName];

            ResourceItem resourceItem = new ResourceItem(resourceName);
            AddResourceItem(resourceItem);

            resourceItem.LoadFromScript();

            return resourceItem;
        }

        public ResourceItem this[string resourceName]
        {
            get
            {
                try { return resourceDictionary[resourceName]; }
                catch { return LoadResource(resourceName); }
            }
        }

        public bool Contains(string resourceName)
        {
            return resourceDictionary.ContainsKey(resourceName);
        }
    }
}
